///Based on the codebook implementation fro LearningOpencv by Oreilly.
#ifndef BG_CB
#define BG_CB
				
// define all of the opencv classes etc.
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/core/core_c.h>
#include <cv.h>
using namespace cv;
#define CHANNELS 3

typedef struct code_word{
	uchar learnHigh[CHANNELS]; //High side threshold for learning
	uchar learnLow[CHANNELS]; //Low side threshold for learning
	uchar max[CHANNELS]; //High side of box boundary
	uchar min[CHANNELS]; //Low side of box boundary
	int t_last_update;	 //This is book keeping to allow us to kill stale entries
	int stale;	//max negative run (biggest period of inactivity)
} codeWord;

typedef struct code_book {
	int cbBounds[3];
    int modMin[3];
    int modMax[3];
	codeWord **cb;
	int numEntries;	//number of entries in the codebook
	int t;	//count every access
} codeBook;


int findBiggestContourIndex(vector<vector<Point>>&contours, int minimPerimeter);

///
///p - pointer to a YCrCb pixel ...
///c - codebook of this pixel
///index - index of the pixel
///numChannles - default 3
///
int updateCodeBook(uchar *p, codeBook *c, int index, int numChannels = 3);

///////////////////////////////////////////////////////////////////////////////////
// uchar cvbackgroundDiff(uchar *p, codeBook &c, int minMod, int maxMod)
// Given a pixel and a code book, determine if the pixel is covered by the codebook
//
// p		pixel pointer (YCrCb interleaved)
// c		codebook reference
// numChannels  Number of channels we are testing
// NOTES: YCrCb
// minMod and maxMod must have length numChannels, e.g. 3 channels => minMod[3], maxMod[3].
//
// Return
// 0 => background, 255 => foreground
uchar computeBackgroundDiff(uchar *p, codeBook *c, int k, int numChannels);



//UTILITES////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////
//int clearStaleEntries(codeBook &c)
// After you've learned for some period of time, periodically call this to clear out stale codebook entries
//
//c		Codebook to clean up
//
// Return
// number of entries cleared
int clearStaleEntries(codeBook &c);

void processMask(Mat& fgMask);

#endif

